import { app } from "../../../scripts/app.js";
import { ComfyWidgets } from "../../../scripts/widgets.js";

// Function to send path open request to backend
async function openPath(path) {
    try {
        const response = await fetch("/grover/open_path", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({ path: path }),
        });

        const result = await response.json();

        if (result.success) {
            console.log("✅ Path opened successfully:", result.message);
            // You could show a toast notification here if available
        } else {
            console.error("❌ Failed to open path:", result.error);
            alert(`Failed to open path: ${result.error}`);
        }
    } catch (error) {
        console.error("❌ Network error opening path:", error);
        alert(`Network error: ${error.message}`);
    }
}

// Custom button widget implementation
class OpenPathButtonWidget {
    constructor(name, value, callback, options = {}) {
        this.name = name;
        this.type = "button";
        this.value = value;
        this.callback = callback;
        this.options = options;
        this.size = [0, 30]; // Height of 30px for the button
    }

    draw(ctx, node, width, y, height) {
        const margin = 10;
        const buttonWidth = width - margin * 2;
        const buttonHeight = height - 4;
        const buttonX = margin;
        const buttonY = y + 2;

        // Button background
        ctx.fillStyle = this.options.pressed ? "#4a5c6a" : "#5a6c7a";
        ctx.fillRect(buttonX, buttonY, buttonWidth, buttonHeight);

        // Button border
        ctx.strokeStyle = "#8a9aa8";
        ctx.lineWidth = 1;
        ctx.strokeRect(buttonX, buttonY, buttonWidth, buttonHeight);

        // Button text
        ctx.fillStyle = "#ffffff";
        ctx.font = "12px Arial";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";

        const text = this.value || "📁 Open Path";
        ctx.fillText(
            text,
            buttonX + buttonWidth / 2,
            buttonY + buttonHeight / 2
        );
    }

    mouse(event, pos, node) {
        if (event.type === "pointerdown") {
            this.options.pressed = true;
            node.setDirtyCanvas(true);
            return true;
        } else if (event.type === "pointerup") {
            if (this.options.pressed) {
                this.options.pressed = false;
                node.setDirtyCanvas(true);

                // Execute the callback
                if (this.callback) {
                    this.callback();
                }
                return true;
            }
        }
        return false;
    }

    computeSize(width) {
        return [width, 30];
    }
}

// Register the extension
app.registerExtension({
    name: "Grover.OpenPathNode",

    async beforeRegisterNodeDef(nodeType, nodeData) {
        if (nodeData.name === "OpenPathNode") {
            // Store the original onNodeCreated function
            const onNodeCreated = nodeType.prototype.onNodeCreated;

            // Override onNodeCreated to add our custom button
            nodeType.prototype.onNodeCreated = function () {
                // Call the original onNodeCreated if it exists
                if (onNodeCreated) {
                    onNodeCreated.apply(this, arguments);
                }

                // Add the custom open path button
                const openButton = new OpenPathButtonWidget(
                    "open_path_button",
                    "📁 Open Path",
                    () => {
                        // Function to get the current path value
                        const getCurrentPath = () => {
                            // First, check if there's a connected input for the path
                            const pathInput = this.inputs?.find(
                                (input) => input.name === "path"
                            );
                            if (pathInput && pathInput.link) {
                                // If there's a connected input, we can't get dynamic values from frontend
                                // Return empty string to let backend handle it via last executed path
                                return "";
                            }

                            // If no connected input, check the manual path widget
                            const pathWidget = this.widgets.find(
                                (w) => w.name === "path"
                            );
                            return pathWidget ? pathWidget.value : "";
                        };

                        const path = getCurrentPath();

                        // Always try to open the path, let the backend handle the logic
                        // The backend will use the provided path or fall back to last executed path
                        openPath(path);
                    },
                    { pressed: false }
                );

                // Add the button widget to the node
                this.addCustomWidget(openButton);

                // Set node properties
                this.serialize_widgets = true;
                this.size = this.computeSize();
            };

            // Override serialize to exclude our button from serialization
            const onSerialize = nodeType.prototype.onSerialize;
            nodeType.prototype.onSerialize = function (o) {
                if (onSerialize) {
                    onSerialize.apply(this, arguments);
                }

                // Remove button widget values from serialization
                if (o.widgets_values) {
                    o.widgets_values = o.widgets_values.filter((_, index) => {
                        const widget = this.widgets[index];
                        return widget && widget.name !== "open_path_button";
                    });
                }
            };

            // Override configure to handle loading
            const onConfigure = nodeType.prototype.onConfigure;
            nodeType.prototype.onConfigure = function (o) {
                if (onConfigure) {
                    onConfigure.apply(this, arguments);
                }

                // Ensure the button is recreated after loading
                setTimeout(() => {
                    if (
                        !this.widgets.some((w) => w.name === "open_path_button")
                    ) {
                        const openButton = new OpenPathButtonWidget(
                            "open_path_button",
                            "📁 Open Path",
                            () => {
                                // Function to get the current path value
                                const getCurrentPath = () => {
                                    // First, check if there's a connected input for the path
                                    const pathInput = this.inputs?.find(
                                        (input) => input.name === "path"
                                    );
                                    if (pathInput && pathInput.link) {
                                        // If there's a connected input, we can't get dynamic values from frontend
                                        // Return empty string to let backend handle it via last executed path
                                        return "";
                                    }

                                    // If no connected input, check the manual path widget
                                    const pathWidget = this.widgets.find(
                                        (w) => w.name === "path"
                                    );
                                    return pathWidget ? pathWidget.value : "";
                                };

                                const path = getCurrentPath();

                                // Always try to open the path, let the backend handle the logic
                                // The backend will use the provided path or fall back to last executed path
                                openPath(path);
                            },
                            { pressed: false }
                        );
                        this.addCustomWidget(openButton);
                        this.size = this.computeSize();
                    }
                }, 10);
            };
        }
    },
});
